home *** CD-ROM | disk | FTP | other *** search
/ Video Toaster 4.3 / Video Toaster v4.3.iso / 3.1 / toasterall / arexx_examples / lwm / commandseqproc.lwm < prev    next >
Text File  |  1993-08-08  |  4KB  |  157 lines

  1. /*
  2.  * SEQ -- Command Sequence Processor
  3.  *
  4.  * This takes a shell command with special pattern codes embedded in it
  5.  * and issues a sequence of shell commands generated by filling in the
  6.  * patterns.  This allows for one-line processing of a sequence of files
  7.  * such as LightWave image sequences.
  8.  *
  9.  * Some examples:
  10.  *
  11.  *    CLI> seq copy abc#30# abc#.bku
  12.  *    copy abc001 abc001.bku
  13.  *    copy abc002 abc002.bku
  14.  *     ...
  15.  *    copy abc030 abc030.bku
  16.  *
  17.  *    CLI> seq rename img#1,20,2# ximg#3,10#
  18.  *    rename img001 ximg003
  19.  *    rename img003 ximg004
  20.  *    rename img005 ximg005
  21.  *     ...
  22.  *    rename img017 ximg011
  23.  *    rename img019 ximg012
  24.  *
  25.  * It takes the command line and breaks it up into words.  Each word
  26.  * can contain a sequence pattern which will be expanded into a sequence
  27.  * of words with numbers replacing the pattern code.  The codes can be
  28.  * in the following forms:
  29.  *
  30.  *      pattern form          start    end     step
  31.  *      ------------          -----    ---     ----
  32.  *     #            1    1    1
  33.  *     #N#            1    N    1
  34.  *     #K,N#            K    N    1
  35.  *     #K,N,S#        K    N    S
  36.  *
  37.  * Any word without a pattern is just a constant which gets repeated
  38.  * in each iteration.  The total number of iterations for the combined
  39.  * command is the MAXIMUM number of elements in any sequence.
  40.  *
  41.  * If the command line is preceded by a hyphen (i.e. "seq -copy ..."),
  42.  * the commands will be generated and displayed but not envoked as
  43.  * shell commands.  This allows you to test a complex pattern before
  44.  * letting it work on real files.
  45.  *
  46.  * This should be placed in the "S:" directory and have its script bit
  47.  * set to work as indicated in the above examples.
  48.  *
  49.  * 7/93        Stuart Ferguson
  50.  */
  51.  
  52.  
  53. call addlib("rexxsupport.library",0,-30,0)
  54.  
  55. /* Get command line from shell.
  56.  */
  57. parse arg cmdline
  58.  
  59. /* Look for leading hyphen to see if this is a real command.
  60.  */
  61. forreal = 1
  62. cmdline = strip(cmdline)
  63. if (left(cmdline, 1) = '-') then do
  64.     forreal = 0
  65.     cmdline = strip(substr(cmdline,2))
  66. end
  67.  
  68. /* Get number of words on command line.
  69.  */
  70. narg = words(cmdline)
  71. if (narg < 1) then exit 10
  72.  
  73. /* Convert each word into sequence form and get the max sequence size
  74.  * as the number of iterations.
  75.  */
  76. iter = 1
  77. do i=1 to narg
  78.     templ.i = namebreak(word(cmdline,i))
  79.     iter = max(iter, namecount(templ.i))
  80. end i
  81.  
  82. /* Generate a new command line by expanding each sequence pattern into
  83.  * a specific instance for each iteration.
  84.  */
  85. do k=1 to iter
  86.     cmd = ""
  87.     do i=1 to narg
  88.     cmd = cmd || iname(k,templ.i) || ' '
  89.     end i
  90.  
  91.     say cmd
  92.     if (forreal) then address command cmd
  93. end k
  94.  
  95. exit
  96.  
  97.  
  98.  
  99. /*
  100.  * NameBreak converts a pattern word into a sequence descriptor.  The
  101.  * descriptor consists of five words: name pattern, number of digits,
  102.  * start index, step, end index.  Pattern is a word with a '*' in it
  103.  * where the number will go.
  104.  */
  105. NAMEBREAK: procedure
  106.     parse arg name
  107.  
  108.     /* Find first pattern marker.  If none, this is a constant sequence.
  109.      */
  110.     p1 = pos('#',name)
  111.     if (p1 = 0) then return name || "* 0 1 1 1"
  112.  
  113.     /* Find second pattern marker, if any.
  114.      */
  115.     p2 = pos('#',name,p1+1)
  116.     if (p2 = 0) then p2 = p1
  117.  
  118.     /* Split out head and tail sections.  If no second pattern marker,
  119.      * just set defaults.
  120.      */
  121.     head = substr(name,1,p1-1)
  122.     tail = substr(name,p2+1)
  123.     pat = head || "*" || tail
  124.     if (p1 = p2) then return pat 3 1 1 1
  125.  
  126.     /* Parse sequence numbers.  Step defaults to 1.  Start defaults to 1.
  127.      */
  128.     larg = substr(name,p1+1,p2-p1-1)
  129.     parse var larg n0 ',' n1 ',' step
  130.     if (step = "") then step = 1
  131.     if (n1 = "") then do
  132.     n1 = n0
  133.     n0 = 1
  134.     end
  135.  
  136.     return pat 3 n0 step n1
  137.  
  138.  
  139. /*
  140.  * NameCount takes a sequence descriptor and returns the number of elements
  141.  * defined by the sequence.
  142.  */
  143. NAMECOUNT: procedure
  144.     arg pat ndig n0 step n1 .
  145.     return (n1 - n0 + step) % step
  146.  
  147.  
  148. /*
  149.  * IName takes an index and sequence descriptor and returns the name 
  150.  * generated for the given index.
  151.  */
  152. INAME: procedure
  153.     parse arg i, pat ndig n0 step .
  154.     parse var pat head '*' tail
  155.     num = right(n0 + step * (i - 1), ndig, 0)
  156.     return head || num || tail
  157.